/**
 * 智能市场数据获取Hook
 * ===================
 * 
 * 根据数据更新频率和连接状态智能选择WebSocket或HTTP轮询
 * 支持自动故障转移和性能优化
 */

import { useState, useEffect, useCallback, useRef } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { WebSocketManager, WebSocketMessage } from '../websocket/WebSocketManager';
import { getMarketDataWebSocketManager } from '../websocket';

export interface DataOptions {
  symbol: string;
  updateFrequency: number; // 更新频率(毫秒)
  priority: 'realtime' | 'normal' | 'low';
  fallbackToPolling: boolean;
  maxRetries: number;
  retryDelay: number;
}

export interface MarketData {
  symbol: string;
  price: number;
  change: number;
  changePercent: number;
  volume: number;
  timestamp: number;
  [key: string]: any;
}

export interface UseSmartMarketDataResult {
  data: MarketData | null;
  error: Error | null;
  isLoading: boolean;
  strategy: 'websocket' | 'polling' | 'hybrid';
  isConnected: boolean;
  retryCount: number;
  refetch: () => void;
}

// 默认配置
const DEFAULT_OPTIONS: Partial<DataOptions> = {
  updateFrequency: 1000,
  priority: 'normal',
  fallbackToPolling: true,
  maxRetries: 3,
  retryDelay: 1000
};

// 策略选择阈值
const STRATEGY_THRESHOLDS = {
  WEBSOCKET_MIN_FREQUENCY: 5000, // 5秒内更新使用WebSocket
  POLLING_MAX_FREQUENCY: 30000,  // 30秒以上更新使用轮询
  HYBRID_FREQUENCY_RANGE: [5000, 30000] // 混合模式频率范围
};

/**
 * 智能市场数据获取Hook
 */
export function useSmartMarketData(
  options: Partial<DataOptions> = {},
  wsManager?: WebSocketManager
): UseSmartMarketDataResult {
  const config = { ...DEFAULT_OPTIONS, ...options } as DataOptions;
  const queryClient = useQueryClient();
  
  // 状态管理
  const [data, setData] = useState<MarketData | null>(null);
  const [error, setError] = useState<Error | null>(null);
  const [strategy, setStrategy] = useState<'websocket' | 'polling' | 'hybrid'>('polling');
  const [retryCount, setRetryCount] = useState(0);
  const [isConnected, setIsConnected] = useState(false);
  
  // 引用
  const wsManagerRef = useRef<WebSocketManager | null>(wsManager || null);
  const lastDataRef = useRef<MarketData | null>(null);
  const retryTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // 确定数据获取策略
  const determineStrategy = useCallback((): 'websocket' | 'polling' | 'hybrid' => {
    const { updateFrequency, priority } = config;
    
    // 如果WebSocket不可用，强制使用轮询
    if (!wsManagerRef.current || !wsManagerRef.current.isConnected()) {
      return 'polling';
    }
    
    // 根据更新频率选择策略
    if (updateFrequency <= STRATEGY_THRESHOLDS.WEBSOCKET_MIN_FREQUENCY) {
      return 'websocket';
    } else if (updateFrequency >= STRATEGY_THRESHOLDS.POLLING_MAX_FREQUENCY) {
      return 'polling';
    } else if (priority === 'realtime') {
      return 'websocket';
    } else {
      return 'hybrid';
    }
  }, [config]);

  // HTTP轮询查询
  const {
    data: pollingData,
    error: pollingError,
    isLoading: isPollingLoading,
    refetch: refetchPolling
  } = useQuery({
    queryKey: ['market-data', config.symbol, 'polling'],
    queryFn: async () => {
      const response = await fetch(`/api/v1/market/index?code=${config.symbol}&source=tushare`);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      const result = await response.json();
      
      // 将API返回的index数据转换为MarketData格式
      if (result.success && result.data) {
        const apiData = result.data;
        return {
          symbol: apiData.code,
          name: apiData.name,
          price: apiData.current,
          change: apiData.change,
          changePercent: apiData.change_pct,
          high: apiData.high,
          low: apiData.low,
          open: apiData.open,
          volume: apiData.volume,
          amount: 0, // API没有返回amount
          timestamp: apiData.timestamp
        } as MarketData;
      }
      
      throw new Error('API返回格式错误');
    },
    enabled: strategy === 'polling' || strategy === 'hybrid',
    refetchInterval: strategy === 'polling' ? config.updateFrequency : false,
    retry: config.maxRetries,
    retryDelay: config.retryDelay,
    staleTime: config.updateFrequency / 2,
    gcTime: config.updateFrequency * 2,
    // 保留之前的数据，避免在后台刷新时显示loading
    placeholderData: (previousData) => previousData
  });

  // WebSocket消息处理
  const handleWebSocketMessage = useCallback((message: WebSocketMessage) => {
    if (message.type === 'data' && message.data?.symbol === config.symbol) {
      const marketData: MarketData = {
        symbol: message.data.symbol,
        price: message.data.data?.price || 0,
        change: message.data.data?.change || 0,
        changePercent: message.data.data?.changePercent || 0,
        volume: message.data.data?.volume || 0,
        timestamp: message.timestamp,
        ...message.data.data
      };
      
      setData(marketData);
      setError(null);
      setRetryCount(0);
      lastDataRef.current = marketData;
    }
  }, [config.symbol]);

  // 初始化WebSocket管理器
  useEffect(() => {
    if (!wsManagerRef.current && typeof window !== 'undefined') {
      // 使用工厂函数获取单例 WebSocketManager
      getMarketDataWebSocketManager(
        {
          onConnect: () => {
            console.log('[useSmartMarketData] WebSocket connected successfully');
            setIsConnected(true);
          },
          onDisconnect: () => {
            console.log('[useSmartMarketData] WebSocket disconnected');
            setIsConnected(false);
          },
          onMessage: handleWebSocketMessage,
          onError: (error) => {
            console.error('[useSmartMarketData] WebSocket error:', error);
            setError(new Error('WebSocket connection error'));
          }
        },
        {
          reconnectDelay: 5000,
          maxReconnectAttempts: 10,
          heartbeatInterval: 30000
        }
      ).then(manager => {
        wsManagerRef.current = manager;
        
        // 立即尝试连接
        manager.connect().catch(err => {
          console.error('[useSmartMarketData] Failed to connect WebSocket:', err);
        });
      }).catch(err => {
        console.error('[useSmartMarketData] Failed to initialize WebSocket:', err);
      });
    }
  }, [handleWebSocketMessage]);

  // 策略切换
  useEffect(() => {
    const newStrategy = determineStrategy();
    setStrategy(newStrategy);
  }, [determineStrategy]);

  // WebSocket订阅管理
  useEffect(() => {
    if (strategy === 'websocket' || strategy === 'hybrid') {
      if (wsManagerRef.current && wsManagerRef.current.isConnected()) {
        wsManagerRef.current.subscribe([config.symbol]);
        setIsConnected(true);
      }
    } else {
      if (wsManagerRef.current) {
        wsManagerRef.current.unsubscribe([config.symbol]);
      }
    }
  }, [strategy, config.symbol]);

  // 轮询数据处理
  useEffect(() => {
    if (strategy === 'polling' && pollingData) {
      setData(pollingData);
      setError(null);
      setRetryCount(0);
      lastDataRef.current = pollingData;
    }
  }, [strategy, pollingData]);

  // 错误处理
  useEffect(() => {
    if (pollingError) {
      setError(pollingError as Error);
      
      // 如果启用故障转移，尝试切换到WebSocket
      if (config.fallbackToPolling && strategy === 'polling' && wsManagerRef.current?.isConnected()) {
        console.log('Switching to WebSocket due to polling error');
        setStrategy('websocket');
      }
    }
  }, [pollingError, config.fallbackToPolling, strategy]);

  // 重试逻辑
  const retry = useCallback(() => {
    if (retryCount >= config.maxRetries) {
      setError(new Error('Max retry attempts reached'));
      return;
    }

    setRetryCount(prev => prev + 1);
    
    if (retryTimeoutRef.current) {
      clearTimeout(retryTimeoutRef.current);
    }

    retryTimeoutRef.current = setTimeout(() => {
      if (strategy === 'polling') {
        refetchPolling();
      } else if (strategy === 'websocket' && wsManagerRef.current) {
        wsManagerRef.current.connect();
      }
    }, config.retryDelay * retryCount);
  }, [retryCount, config.maxRetries, config.retryDelay, strategy, refetchPolling]);

  // 手动刷新
  const refetch = useCallback(() => {
    setError(null);
    setRetryCount(0);
    
    if (strategy === 'polling') {
      refetchPolling();
    } else if (strategy === 'websocket' && wsManagerRef.current) {
      // 重新订阅
      wsManagerRef.current.unsubscribe([config.symbol]);
      wsManagerRef.current.subscribe([config.symbol]);
    }
  }, [strategy, config.symbol, refetchPolling]);

  // 清理
  useEffect(() => {
    return () => {
      if (retryTimeoutRef.current) {
        clearTimeout(retryTimeoutRef.current);
      }
    };
  }, []);

  // 计算加载状态：只有在没有任何数据且正在加载时才返回 loading
  const currentData = data || lastDataRef.current;
  const baseLoading = strategy === 'polling' ? isPollingLoading : false;
  const isLoading = baseLoading && !currentData;
  
  console.log('[useSmartMarketData] 单个数据加载状态:', {
    symbol: config.symbol,
    strategy,
    baseLoading,
    hasData: !!currentData,
    isLoading,
    isConnected
  });

  return {
    data: currentData,
    error,
    isLoading,
    strategy,
    isConnected,
    retryCount,
    refetch
  };
}

/**
 * 批量市场数据获取Hook
 */
export function useBatchMarketData(
  symbols: string[],
  options: Partial<DataOptions> = {}
) {
  const results = symbols.map(symbol => 
    useSmartMarketData({ ...options, symbol })
  );

  const dataArray = results.map(result => result.data).filter(Boolean);
  
  // 修复加载逻辑：只有在没有任何数据且正在加载时才返回 loading
  // 如果已有数据，即使后台在刷新也不显示 loading
  const hasAnyData = dataArray.length > 0;
  const anyLoading = results.some(result => result.isLoading);
  const shouldShowLoading = anyLoading && !hasAnyData;

  console.log('[useBatchMarketData] 批量加载状态:', {
    symbols,
    resultsCount: results.length,
    dataCount: dataArray.length,
    hasAnyData,
    anyLoading,
    shouldShowLoading,
    individualLoadingStates: results.map((r, i) => ({ 
      symbol: symbols[i], 
      isLoading: r.isLoading, 
      hasData: !!r.data,
      strategy: r.strategy
    }))
  });

  return {
    data: dataArray,
    errors: results.map(result => result.error).filter(Boolean),
    isLoading: shouldShowLoading,
    strategies: results.map(result => result.strategy),
    isConnected: results.some(result => result.isConnected),
    refetch: () => results.forEach(result => result.refetch())
  };
}

/**
 * 市场数据订阅Hook（仅WebSocket）
 */
export function useMarketDataSubscription(
  symbols: string[],
  onData: (data: MarketData) => void,
  wsManager?: WebSocketManager
) {
  const wsManagerRef = useRef<WebSocketManager | null>(wsManager || null);

  useEffect(() => {
    if (!wsManagerRef.current && typeof window !== 'undefined') {
      // 使用工厂函数获取单例 WebSocketManager
      getMarketDataWebSocketManager({
        onMessage: (message) => {
          if (message.type === 'data' && symbols.includes(message.data?.symbol)) {
            const marketData: MarketData = {
              symbol: message.data.symbol,
              price: message.data.data?.price || 0,
              change: message.data.data?.change || 0,
              changePercent: message.data.data?.changePercent || 0,
              volume: message.data.data?.volume || 0,
              timestamp: message.timestamp,
              ...message.data.data
            };
            onData(marketData);
          }
        }
      }).then(manager => {
        wsManagerRef.current = manager;
        
        console.log('[useMarketDataSubscription] WebSocket initialized');
        
        // 立即尝试连接
        manager.connect().catch(err => {
          console.error('[useMarketDataSubscription] Failed to connect WebSocket:', err);
        });
      }).catch(err => {
        console.error('[useMarketDataSubscription] Failed to initialize WebSocket:', err);
      });
    }
  }, [symbols, onData]);

  useEffect(() => {
    if (wsManagerRef.current && wsManagerRef.current.isConnected()) {
      wsManagerRef.current.subscribe(symbols);
    }
  }, [symbols]);

  useEffect(() => {
    return () => {
      if (wsManagerRef.current) {
        wsManagerRef.current.unsubscribe(symbols);
      }
    };
  }, [symbols]);
}
